/***************************************************************************
 * Copyright (C) 2011
 * by Dj_Skual
 *
 * This software is provided 'as-is', without any express or implied
 * warranty. In no event will the authors be held liable for any
 * damages arising from the use of this software.
 *
 * Permission is granted to anyone to use this software for any
 * purpose, including commercial applications, and to alter it and
 * redistribute it freely, subject to the following restrictions:
 *
 * 1. The origin of this software must not be misrepresented; you
 * must not claim that you wrote the original software. If you use
 * this software in a product, an acknowledgment in the product
 * documentation would be appreciated but is not required.
 *
 * 2. Altered source versions must be plainly marked as such, and
 * must not be misrepresented as being the original software.
 *
 * 3. This notice may not be removed or altered from any source
 * distribution.
 *
 * LanguagesSelectBrowser
 *
 * for SaveGame Manager GX 2011
 ***************************************************************************/
#include "LanguagesSelectBrowser.hpp"
#include "../Controls/Application.h"
#include "../Themes/CTheme.h"
#include "CLangList.hpp"

#define LISTSIZE	10

LanguagesSelectBrowser::LanguagesSelectBrowser()
	: GuiFrame(472, 436)
{
	numEntries = LangList.GetCount();
	selectedItem = 0;
	pageIndex = 0;
	running = true;
	
	btnSoundClick = Resources::GetSound("button_click.wav");
	btnSoundOver = Resources::GetSound("button_over.wav");
	btnSoundClick->SetVolume(Settings.SFXVolume);
	btnSoundOver->SetVolume(Settings.SFXVolume);
	
	trigA.SetSimpleTrigger(-1, WiiControls.ClickButton | ClassicControls.ClickButton << 16, GCControls.ClickButton);
	
	WindowImgData = Resources::GetImageData("dialogue_box.png");
	BrowserImgData = Resources::GetImageData("browser.png");
	ButtonBoxImgData = Resources::GetImageData("browser_select_button_box.png");
	ListSelectionImgData = Resources::GetImageData("browser_bg_selection.png");

	WindowImg = new GuiImage(WindowImgData);
	WindowImg->SetScaleY(1.3625);
	
	BrowserImg = new GuiImage(BrowserImgData);
	BrowserImg->SetPosition(-22, 28);
	BrowserImg->SetAlignment(ALIGN_CENTER | ALIGN_TOP);
	BrowserImg->SetScaleX(0.6233);
	BrowserImg->SetScaleY(1.0435);
	
	ButtonBoxImgClose = new GuiImage(ButtonBoxImgData);
	ButtonBoxImgClose->SetAlignment(ALIGN_RIGHT | ALIGN_TOP);
	ButtonBoxImgClose->SetPosition(-25, -26);
	ButtonBoxImgVal = new GuiImage(ButtonBoxImgData);
	ButtonBoxImgVal->SetAlignment(ALIGN_RIGHT | ALIGN_TOP);
	ButtonBoxImgVal->SetPosition(-70, -26);
	
	TitleText = new GuiText(tr( "Select Languages" ), 22, thColor("r=0 g=0 b=0 a=255 - prompt windows text color"));
	TitleText->SetAlignment(ALIGN_CENTER | ALIGN_TOP);
	TitleText->SetPosition(-20, -28);
	TitleText->SetMaxWidth(255, SCROLL_HORIZONTAL);
	
	CloseBtn = new PictureButton("button_close.png", "button_close_over.png", btnSoundClick, btnSoundOver);
	CloseBtn->SetAlignment(ALIGN_RIGHT | ALIGN_TOP);
	CloseBtn->SetPosition(-28, -24);
	CloseBtn->SetTrigger(&trigA);
	CloseBtn->Clicked.connect(this, &LanguagesSelectBrowser::OnButtonClick);
	
	ValidBtn = new PictureButton("button_valid.png", "button_valid_over.png", btnSoundClick, btnSoundOver);
	ValidBtn->SetAlignment(ALIGN_RIGHT | ALIGN_TOP);
	ValidBtn->SetPosition(-73, -24);
	ValidBtn->SetTrigger(&trigA);
	ValidBtn->Clicked.connect(this, &LanguagesSelectBrowser::OnButtonClick);
	
	Append(WindowImg);
	Append(BrowserImg);
	Append(TitleText);
	Append(ButtonBoxImgClose);
	Append(ButtonBoxImgVal);
	Append(CloseBtn);
	Append(ValidBtn);
	
	ScrollBar = new Scrollbar(288, Scrollbar::CUSTOMMODE);
	ScrollBar->SetAlignment(ALIGN_RIGHT | ALIGN_TOP);
	ScrollBar->SetPosition(-32, 22);
	ScrollBar->SetScrollSpeed(Settings.ScrollSpeed);
	ScrollBar->SetDPadControl(false);
	ScrollBar->listChanged.connect(this, &LanguagesSelectBrowser::OnListChange);
	//ScrollBar->SetButtonScroll(WiiControls.OneButtonScroll | ClassicControls.OneButtonScroll << 16, GCControls.OneButtonScroll);
	
	for(int i = 0; i < LISTSIZE; ++i)
		AddButton();
	
	ScrollBar->SetEntrieCount(numEntries);
	ScrollBar->SetPageSize(LISTSIZE);
	ScrollBar->SetRowSize(0);
	ScrollBar->SetSelected(0, 0);
	Append(ScrollBar);
	
	SetAlignment(ALIGN_CENTER | ALIGN_MIDDLE);
	SetPosition(0, 38);
	SetEffect(EFFECT_FADE, 20);
	
	Application::Instance()->Append(this);
	Application::Instance()->SetUpdateOnly(this);
}

LanguagesSelectBrowser::~LanguagesSelectBrowser()
{
	RemoveAll();

	delete WindowImg;
	delete BrowserImg;
	delete ButtonBoxImgClose;
	delete ButtonBoxImgVal;

	Resources::Remove(WindowImgData);
	Resources::Remove(BrowserImgData);
	Resources::Remove(ButtonBoxImgData);
	Resources::Remove(ListSelectionImgData);

	Resources::Remove(btnSoundClick);
	Resources::Remove(btnSoundOver);

	delete TitleText;

	delete ScrollBar;

	delete ValidBtn;
	delete CloseBtn;
	
	while(ListBtn.size() > 0)
		RemoveButton(0);
}

void LanguagesSelectBrowser::AddButton()
{
	int size = ListBtn.size();

	ListBtnText.resize(size+1);
	ListBtnText[size] = new GuiText((char*) NULL, 20, thColor("r=0 g=0 b=0 a=255 - prompt languageSelect list text color"));
	ListBtnText[size]->SetAlignment(ALIGN_LEFT | ALIGN_MIDDLE);
	ListBtnText[size]->SetPosition(25+28, 0);
	ListBtnText[size]->SetMaxWidth(360 - (25+28), DOTTED);

	ListBtnTextOver.resize(size+1);
	ListBtnTextOver[size] = new GuiText((char*) NULL, 20, thColor("r=0 g=0 b=0 a=255 - prompt languageSelect list text color"));
	ListBtnTextOver[size]->SetAlignment(ALIGN_LEFT | ALIGN_MIDDLE);
	ListBtnTextOver[size]->SetPosition(25+28, 0);
	ListBtnTextOver[size]->SetMaxWidth(360 - (25+28), SCROLL_HORIZONTAL);

	ListSelectionImg.resize(size+1);
	ListSelectionImg[size] = new GuiImage(ListSelectionImgData);
	ListSelectionImg[size]->SetScaleX(0.8);
	
	ListBtnCheckbox.resize(size+1);
	ListBtnCheckbox[size] = new GuiCheckbox(20, 20, GuiCheckbox::CHECKSIGN);
	ListBtnCheckbox[size]->SetAlignment(ALIGN_LEFT | ALIGN_TOP);
	ListBtnCheckbox[size]->SetPosition(40, 28*size+32);
	ListBtnCheckbox[size]->SetChecked(false);
	
	ListBtn.resize(size+1);
	ListBtn[size] = new GuiButton(364, 28);
	ListBtn[size]->SetLabel(ListBtnText[size]);
	ListBtn[size]->SetLabelOver(ListBtnTextOver[size]);
	ListBtn[size]->SetImageOver(ListSelectionImg[size]);
	ListBtn[size]->SetAlignment(ALIGN_CENTER | ALIGN_TOP);
	ListBtn[size]->SetPosition(-40, 28*size+26);
	ListBtn[size]->SetTrigger(&trigA);
	ListBtn[size]->SetSoundClick(btnSoundClick);
	ListBtn[size]->SetRumble(Settings.BrowserRumble);
	ListBtn[size]->Clicked.connect(this, &LanguagesSelectBrowser::OnListClick);
	ListBtn[size]->StateChanged.connect(this, &LanguagesSelectBrowser::OnButtonStateChange);
	ListBtn[size]->SetState(STATE_DISABLED);
	
	Append(ListBtn[size]);
	Append(ListBtnCheckbox[size]);
}

void LanguagesSelectBrowser::RemoveButton(int i)
{
	if(i < 0 || i >= (int) ListBtn.size())
		return;

	if(ListBtnText[i])
		delete ListBtnText[i];
	if(ListBtnTextOver[i])
		delete ListBtnTextOver[i];
	if(ListSelectionImg[i])
		delete ListSelectionImg[i];
	if(ListBtnCheckbox[i])
		delete ListBtnCheckbox[i];
	if(ListBtn[i])
		delete ListBtn[i];

	ListBtnText.erase(ListBtnText.begin()+i);
	ListBtnTextOver.erase(ListBtnTextOver.begin()+i);
	ListSelectionImg.erase(ListSelectionImg.begin()+i);
	ListBtnCheckbox.erase(ListBtnCheckbox.begin()+i);
	ListBtn.erase(ListBtn.begin()+i);
}

void LanguagesSelectBrowser::OnButtonStateChange(GuiElement *sender, int state, int stateChan UNUSED)
{
	for(int i = 0; i < LISTSIZE && i < numEntries; i++)
	{
		if(sender == ListBtn[i])
		{
			if(state == STATE_SELECTED)
			{
				selectedItem = i;
				break;
			}
		}
	}
	
	if(ListBtn[selectedItem]->GetState() == STATE_DEFAULT)
		ListBtn[selectedItem]->SetState(STATE_SELECTED);
	
	ScrollBar->SetSelectedItem(selectedItem);
}

void LanguagesSelectBrowser::OnButtonClick(GuiButton *sender, int pointer UNUSED, const POINT &p UNUSED)
{
	Application::Instance()->ResetPads();
	
	if (sender == CloseBtn)
		LangList.Reset();
	
	SetEffect(EFFECT_FADE, -20);
	while(IsAnimated())
		Application::Instance()->updateEvents();
	
	Close();
	running = false;
}

void LanguagesSelectBrowser::OnListClick(GuiButton *sender, int pointer UNUSED, const POINT &p UNUSED)
{
	Application::Instance()->ResetPads();
	
	for(u32 i = 0; i < ListBtn.size(); i++)
	{
		if(ListBtn[i] == sender)
		{
			LangList.SetNeeded(pageIndex + i, !LangList.Needed(pageIndex + i));
			ListBtnCheckbox[i]->SetChecked(LangList.Needed(pageIndex + i));
			break;
		}
	}
}

void LanguagesSelectBrowser::OnListChange(int selItem, int selIndex)
{
	selectedItem = selItem;
	pageIndex = selIndex;

	for(int i = 0; i < LISTSIZE; i++)
	{
		if(pageIndex+i < numEntries)
		{
			if(ListBtn[i]->GetState() == STATE_DISABLED)
			{
				ListBtnCheckbox[i]->SetVisible(true);
				ListBtn[i]->SetVisible(true);
				ListBtn[i]->SetState(STATE_DEFAULT);
			}
			
			ListBtnText[i]->SetText(LangList.GetFilename(pageIndex + i));
			ListBtnTextOver[i]->SetText(LangList.GetFilename(pageIndex + i));
			ListBtnCheckbox[i]->SetChecked(LangList.Needed(pageIndex + i));
		}
		else
		{
			ListBtnCheckbox[i]->SetVisible(false);
			ListBtn[i]->SetVisible(false);
			ListBtn[i]->SetState(STATE_DISABLED);
		}
	}
	
	for(int i = 0; i < LISTSIZE; i++)
	{
		if(ListBtn[i]->GetState() == STATE_SELECTED && i != selectedItem)
			ListBtn[i]->SetState(STATE_DEFAULT);
	}
}

void LanguagesSelectBrowser::Update(GuiTrigger * t)
{
	bool ListChanged = false;
	
	if(t->Up())
	{
		if(selectedItem == 0 && pageIndex > 0)
		{
			--pageIndex;
			ListChanged = true;
		}
		else if(pageIndex+selectedItem > 0)
		{
			--selectedItem;
			ListChanged = true;
		}
	}
	else if(t->Down())
	{
		if(pageIndex+selectedItem + 1 < numEntries)
		{
			if(selectedItem == LISTSIZE-1)
			{
				//! move list down by 1
				pageIndex++;
			}
			else
			{
				selectedItem++;
			}
			ListChanged = true;
		}
	}
	else if(t->Left())
	{
		if(pageIndex > 0)
		{
			pageIndex -= LISTSIZE;
			if(pageIndex < 0)
			{
				pageIndex = 0;
				selectedItem = 0;
			}
			ListChanged = true;
		}
	}
	else if(t->Right())
	{
		if(pageIndex < MAX(0, (numEntries-LISTSIZE)))
		{
			pageIndex += LISTSIZE;
			if(pageIndex > numEntries-LISTSIZE)
			{
				pageIndex = MAX(numEntries-LISTSIZE, 0);
				selectedItem = LIMIT(LISTSIZE-1, 0, numEntries-1);
			}
			ListChanged = true;
		}
	}
	
	if(ListChanged)
		ScrollBar->SetSelected(selectedItem, pageIndex);
	
	GuiFrame::Update(t);
}
